[WPF] CheckListBox的实现方式分析

您所在的位置:网站首页 wpf focusable [WPF] CheckListBox的实现方式分析

[WPF] CheckListBox的实现方式分析

2023-03-04 07:00| 来源: 网络整理| 查看: 265

实际项目中常常要实现有CheckBox列表框。但是WPF没有自带这样的一个控件,下面就用Style来实现这样的功能。而对于CheckBox列表框,又常常会有一个Select All的CheckBox来表示当前列表框的选择状态。这个功能也会被包含在下面的示例之中。效果如下图所示。

 

对于单纯的,没有后台数据绑定的情况下,这个功能可以用ItemContainerStyle来实现。代码如下: 

 

CheckListBoxItemContainerStyle                                             

 

 

其中要对Content和ContentTemplate等属性进行绑定,以方便对其进行扩展,保证其通用性。这个Style一般会放在Application级别的Resource中。

对于有后台数据绑定的情况,一般会有双个属性要绑定,一个是CheckBox里的Content,一个是CheckBox的IsChecked。绑定的路径,只有在用一个Style的ListBox那里才知道,所以并不能写在这个Style里,否则会破坏这个Style的通用性。比较合理的方式是基于这个现有的Style进行修改。

 

对于下面的数据类。

DataItem Class public   class  DataItem : INotifyPropertyChanged{     private   string  name;     private   bool  isEnabled;     public   string  Name    {         get  {  return  name; }         set         {            name  =  value;            OnPropertyChanged( " Name " );        }    }     public   bool  IsEnabled    {         get  {  return  isEnabled; }         set         {            isEnabled  =  value;            OnPropertyChanged( " IsEnabled " );        }    }     #region  INotifyPropertyChanged Members      public   event  PropertyChangedEventHandler PropertyChanged;     #endregion      protected   virtual   void  OnPropertyChanged( string  propertyName)    {        PropertyChangedEventHandler temp  =  PropertyChanged;         if  (temp  !=   null )        {            temp( this ,  new  PropertyChangedEventArgs(propertyName));        }    }}

 

 

我们需要下面这个有针对性的Style来应用数据绑定。

DataItemCheckListBoxStyle                                                                                          

 

在上面的Style中,使用了ItemTemplate来指定CheckBox里的Content绑定到的属性,并把ListBoxItem的IsSelected绑定数据的相应属性上。由于这个Style是针对特定数据写的,所以应当放置在使用这个Style的ListBox所在的Window的Resource中。

 

当然,也可以为ListBox添加两个绑定类型的Attached Property来实现一个通用的Style。不过这个Property一样要在使用的地方设置,其实没有太大区别。有兴趣的读者可以自己试一下。

 

对于Select All这个CheckBox而言,用Attached Property倒是很方便。给CheckBox添加一个SyncTarget属性指向要同步的ListBox,就可以在Window.xaml.cs之外的地方同步CheckBox和ListBox了。代码如下:

 

ToggleButtonProperty public   class  ToggleButtonProperty{     //  Using a DependencyProperty as the backing store for SyncTarget.  This enables animation, styling, binding, etc...      public   static   readonly  DependencyProperty SyncTargetProperty  =         DependencyProperty.RegisterAttached( " SyncTarget " ,  typeof (ListBox),  typeof (ToggleButtonProperty),  new  UIPropertyMetadata( new  PropertyChangedCallback(OnSyncTargetChanged)));     public   static  ListBox GetSyncTarget(DependencyObject obj)    {         return  obj.GetValue(SyncTargetProperty)  as  ListBox;    }     public   static   void  SetSyncTarget(DependencyObject obj, ListBox value)    {        obj.SetValue(SyncTargetProperty, value);    }     private   static   void  OnSyncTargetChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)    {        ToggleButton checker  =  sender  as  ToggleButton;         if  (checker  ==   null )        {             throw   new  InvalidOperationException( " SyncTarget property only works on ToggleButton. " );        }        ListBox targetList  =  e.NewValue  as  ListBox;         if  (targetList  ==   null )        {             throw   new  InvalidOperationException( " Sync target must be a ListBox. " );        }         // TODO: Un-subscribe OldValue's Event.         checker.Checked  +=  (s, a)  =>         {            targetList.SelectAll();        };        checker.Unchecked  +=  (s, a)  =>         {            targetList.UnselectAll();        };        targetList.SelectionChanged  +=  (s, a)  =>         {            checker.IsChecked  =  targetList.SelectedItems.Count  ==   0   ?   false  :                targetList.SelectedItems.Count  ==  targetList.Items.Count  ?  ( bool ? ) true  :  null ;        };    }}

 

使用方式也很简单。如下代码所示。

 

用法          

 

 

完整的项目文件可以从这里下载。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3